﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Automation;
using Compiled_Tests.Utils;
using System.Text.RegularExpressions;
using Tedds_Tool.Automatables;
using LEET.LEETCommon.Model;
using LEET.CommonInterfaces.Compilers;
using LEET.LEETCommon;
using LEET.Utilities;
using Compiled_Tests;

namespace Tedds_Tool.Instructions
{
    public class Verify : Instruction
    {
        private string type;
        private string expected;
        private string elementType;
        private string element;
        private string property;
        private string assert;
        private IList<ILEETHackModual> hacks;

        public Verify(string[] args, IList<ILEETHackModual> hacks)
            : base(args)
        {
            this.hacks = hacks;
            assert = "Is";
            type = args[1].Trim();
            elementType = args[3].Trim();
            element = args[2].Trim().Replace("\"", "\\\"");
            property = args[4].Trim();
            if (args.Length == 6)
                expected = args[5].Trim();
            else
            {
                assert = args[5].Trim();
                expected = args[6].Trim();
            }

            Match m = Regex.Match(expected, "\"(.*)\"");
            if (m.Success)
            {
                expected = "\"" + Utilities.Escape(m.Groups[1].Value) + "\"";
            }
            else
            {
                expected = Utilities.Escape(expected);
            }
            InstructionType = NodeTypes.VERIFY_TYPE;
        }

        [Obsolete("This should now be replaced by RenderStaticCall", false)]
        protected override String RenderedMethodName(int i)
        {
            return "_"+i+"_VERIFY";
        }

        public static void StaticCall(String element, IBox box, String elementType)
        {
            //TODO
            AutomationElement ae = new Utilities().getElement(element, box.RootElement);
        }

        public override String RenderStaticCall()
        {
            //TODO
            return "Tedds_Tool.Instructions.Verify.StaticCall()";
        }

        [Obsolete("This should now be replaced by RenderStaticCall", false)]
        protected override String MethodBody(AssertionSet asserts)
        {
            StringBuilder buf = new StringBuilder();
            buf.Append("                ").Append("AutomationElement ae = util.getElement(\"").Append(element).Append("\", Box.RootElement);\r\n");

            if (assert == "Process Exists")
            {
                buf.Append("                ").Append("Process process = Process.GetProcessById(ae.Current.ProcessId);\r\n");
                buf.Append("                ").Append("Assert.IsNotNull(process);\r\n");
                buf.Append("                ").Append("Assert.IsFalse(process.HasExited);\r\n");
            }
            else
            {
                if (type.Equals("ELEMENT"))
                {
                    if (String.IsNullOrEmpty(elementType))
                    {
                        buf.Append("                ").Append("Object actual = ae");
                    }
                    else
                    {
                        string insert = null;
                        foreach (ILEETHackModual hack in hacks)
                        {
                            if (hack.PropertyName.StartsWith(elementType))
                                insert = hack.HackFlag;
                        }
                        if (insert != null)
                        {
                            elementType = "ValuePattern";
                            property = ".Current.Value";
                            insert = "                pattern.SetValue(\"_____" + insert + "\");\r\n";
                        }

                        buf.Append("                ").Append(elementType).Append(" pattern = ae.GetCurrentPattern(").Append(elementType).Append(".Pattern) as ").Append(elementType).Append(";\r\n");
                        buf.Append("").Append(insert); // let the widget know which property we want // HACKY
                        buf.Append("                ").Append("Object actual = pattern");
                    }
                    buf.Append(property).Append(";\r\n");
                }
                else throw new InvalidInstructionException("Invalid Verification : " + Helpers.Join(args, " | "));
                if (assert.Equals("Is"))
                    buf.Append("                ").Append(asserts.assertEquality(expected, "actual")).Append("\r\n");
                else if (assert.Equals("Is Not"))
                    buf.Append("                ").Append(asserts.assertNonEquality(expected, "actual")).Append("\r\n");
                else if (assert.Equals("Is True"))
                    buf.Append("                ").Append(asserts.assertTrue("actual")).Append("\r\n");
                else if (assert.Equals("Is False"))
                    buf.Append("                ").Append(asserts.assertFalse("actual")).Append("\r\n");
                else
                    buf.Append("                ").Append(asserts.assertContains(expected, "actual")).Append("\r\n");
            }

            buf.Append("                ").Append("return new AutomationActionResult();\r\n");
            return buf.ToString();
        }

        private bool AssertEqual {
            get 
            {
                if(assert == null || assert.Equals("Is"))
                    return true;
                return assert == null || assert.Equals("Is");
            }
        }

        public override string PlainText()
        {
            string prop = property;
            if (property.Contains(".Current."))
                 prop = property.Remove(0, ".Current.".Length);
            string[] s = element.Split(',');//s[s.Length - 1]
            return "Checked to see if the \"" + prop + "\" property of \"" + element + "\" was \"" + expected + "\".";
        }

        public override bool Valid
        {
            get
            {
                Errors.Clear();
                if (!type.Equals("ELEMENT") || containsIllegalChar(type)){
                    AddErrorMsg("Invalid Type: " + type);
                }

                if (property.Contains(".Windows.Controls.ComboBoxItem:") || containsIllegalChar(property)){
                    AddErrorMsg("Invalid Property: " + property);
                }

                if (containsIllegalChar(element))
                {
                    AddErrorMsg("Invalid Element: " + element);
                }

                if (expected.Equals("--Arguments--"))
                    AddErrorMsg("Invalid Expectation: " + expected);

                return base.Valid;
            }
        }

        private bool containsIllegalChar(string str)
        {
            return str.Contains('+')
                //|| str.Contains('=')
                || str.Contains('\\')
                || str.Contains('?');
                //|| str.Contains('-');
        }
    }
}
